package com.sig.formes;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import com.sig.opengl.MyGLRenderer;

import android.opengl.GLES20;

public class Triangle extends Forme{

	public Point p0;
	public Point p1;
	public Point p2;

	public Triangle(Point p0,Point p1,Point p2)	{
		this.p0 = p0;
		this.p1 = p1;
		this.p2 = p2;
	}

	public boolean contains(Point p)
	{

		if(     ( determinant( p0, p1, p ) > 0 )
				&&      ( determinant( p1, p2, p ) > 0 )
				&&      ( determinant( p2, p0, p ) > 0 )
				)
		{
			return true;
		}
		if(     ( determinant( p0, p1, p ) < 0 )
				&&      ( determinant( p1, p2, p ) < 0 )
				&&      ( determinant( p2, p0, p ) < 0 )
				)
		{
			return true;
		}
		return false;

	}

	public double determinant(Point p0,Point p1,Point p2 )
	{
		return ( ( p0.x-p1.x )*( p2.y - p1.y ) ) - ( ( p2.x-p1.x )*( p0.y-p1.y ) );
	}

	public Point getCenter()
	{
		return new Point( ( p0.x + p1.x + p2.x ) / 3, ( p0.y + p1.y + p2.y ) / 3 );
	}




	/////////////////////////// OPENGL ///////////////////////





	private final String vertexShaderCode =

		    // This matrix member variable provides a hook to manipulate
		    // the coordinates of objects that use this vertex shader.
		    "uniform mat4 uMVPMatrix;   \n" +

		    "attribute vec4 vPosition;  \n" +
		    "void main(){               \n" +
		    // The matrix must be included as part of gl_Position
		    // Note that the uMVPMatrix factor *must be first* in order
		    // for the matrix multiplication product to be correct.
		    " gl_Position = vPosition * uMVPMatrix; \n" +

		    "}  \n";

	private final String fragmentShaderCode =
			"precision mediump float;" +
				    "uniform vec4 vColor;" +
				    "void main() {" +
				    "  gl_FragColor = vColor;" +
				    "}";

	private FloatBuffer vertexBuffer;
	private int mProgram;
	private int mPositionHandle;
	private int mColorHandle;
	private int mMVPMatrixHandle;

	// number of coordinates per vertex in this array
	static final int COORDS_PER_VERTEX = 3;

	private float[] getTriangleCoords(){
		float[] triangleCoords = new float[9];

		triangleCoords[0] = p0.getOpenGLX();
		triangleCoords[1] = p0.getOpenGLY();
		triangleCoords[2] = 0;

		triangleCoords[3] = p1.getOpenGLX();
		triangleCoords[4] = p1.getOpenGLY();
		triangleCoords[5] = 0;

		triangleCoords[6] = p2.getOpenGLX();
		triangleCoords[7] = p2.getOpenGLY();
		triangleCoords[8] = 0;

		return triangleCoords;
	}

	private int vertexCount = 9 / COORDS_PER_VERTEX;
	private int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

	private void creer(){

		float[] triangleCoords = getTriangleCoords();

		// initialize vertex byte buffer for shape coordinates
		ByteBuffer bb = ByteBuffer.allocateDirect(
				// (number of coordinate values * 4 bytes per float)
				triangleCoords.length * 4);
		// use the device hardware's native byte order
		bb.order(ByteOrder.nativeOrder());

		// create a floating point buffer from the ByteBuffer
		vertexBuffer = bb.asFloatBuffer();
		// add the coordinates to the FloatBuffer
		vertexBuffer.put(triangleCoords);
		// set the buffer to read the first coordinate
		vertexBuffer.position(0);

		// prepare shaders and OpenGL program
		int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
				vertexShaderCode);
		int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
				fragmentShaderCode);

		mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
		GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
		GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
		GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables

	}
	
	public void draw(float[] mvpMatrix) {
		if(!cree){
			this.creer();
			cree=true;
		}
		
		super.draw(mvpMatrix);
		
		GLES20.glUseProgram(mProgram);

		// get handle to vertex shader's vPosition member
		mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

		// Enable a handle to the triangle vertices
		GLES20.glEnableVertexAttribArray(mPositionHandle);

		// Prepare the triangle coordinate data
		GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
				GLES20.GL_FLOAT, false,
				vertexStride, vertexBuffer);

		// get handle to fragment shader's vColor member
		mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

		// Set color for drawing the triangle
		GLES20.glUniform4fv(mColorHandle, 1, getColor(), 0);

		// get handle to shape's transformation matrix
		mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
		MyGLRenderer.checkGlError("glGetUniformLocation");

		// Apply the projection and view transformation
		GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
		MyGLRenderer.checkGlError("glUniformMatrix4fv");

		// Draw the triangle
		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

		// Disable vertex array
		GLES20.glDisableVertexAttribArray(mPositionHandle);
	}

}